// 复合数据类型 --- 续
package main

// func main() {
// 一. 切片
/*
	// 1. make函数 make([]T, len, cap)
	var slice1 = make([]int, 4, 8)
	fmt.Printf("%v, %d, %d\n", slice1, len(slice1), cap(slice1))
	slice1[2] = 3
	fmt.Println(slice1)

	// 2. 扩容 append
	var slice2 []int // len = 0, cap = 0
	// fmt.Println(slice2)
	slice2 = append(slice2, 12)
	fmt.Println(slice2, len(slice2), cap(slice2))
	slice2 = append(slice2, 1, 2, 3, 4)
	fmt.Println(slice2, len(slice2), cap(slice2))
	// 合并切片
	slice2 = append(slice2, slice1...) // 固定语法, 合并用slice_name...
	fmt.Println("slice1", slice1, len(slice1), cap(slice1))
	fmt.Println("slice2", slice2, len(slice2), cap(slice2))
	slice2[2] = 10
	fmt.Println("slice1", slice1, len(slice1), cap(slice1))
	fmt.Println("slice2", slice2, len(slice2), cap(slice2))
	// 扩容策略
	var slice3 []int
	for i := 1; i <= 10; i++ {
		slice3 = append(slice3, i)
		fmt.Println(slice3, "len:", len(slice3), "cap:", cap(slice3))
			[1] len: 1 cap: 1
			[1 2] len: 2 cap: 2
			[1 2 3] len: 3 cap: 4  直接2倍
			[1 2 3 4] len: 4 cap: 4
			[1 2 3 4 5] len: 5 cap: 8  不够再2倍
			[1 2 3 4 5 6] len: 6 cap: 8
			[1 2 3 4 5 6 7] len: 7 cap: 8
			[1 2 3 4 5 6 7 8] len: 8 cap: 8
			[1 2 3 4 5 6 7 8 9] len: 9 cap: 16
			[1 2 3 4 5 6 7 8 9 10] len: 10 cap: 16
	}

	// 3. 复制 copy
	var slice4 = []int{1, 2, 3}
	// slice5 := slice4 // 引用数据类型, 不能直接这样用.
	// fmt.Println(slice4, slice5)
	// slice5[0] = 4
	// fmt.Println(slice4, slice5)
	slice5 := make([]int, len(slice4), len(slice4)) // 先用make方法制作一个长度和容量都大于等于被复制切片的切片.
	copy(slice5, slice4)
	fmt.Println(slice4, slice5)
	slice5[0] = 4
	fmt.Println(slice4, slice5)

	// 4. 删除 没有专门的方法
	var slice6 = []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
	// 删除索引为2的 --> idx： a = append(a[:idx], a[idx+1::]...)
	fmt.Println(slice6)
	slice6 = append(slice6[:2], slice6[3:]...) // 别忘了3个点
	fmt.Println(slice6)

	// 5. 排序算法 sort包
	var slice7 = []int{45, 123, 5467, 11, 45, 476, 13}
	sort.Ints(slice7) // sort.Floats()...
	fmt.Println(slice7)
	// 反序：
	sort.Sort(sort.Reverse(sort.IntSlice(slice7)))
	fmt.Println(slice7)
*/

// 二. map  无序的 Key-Value  很类似于python中的dict
/*
	// 1. 定义及初始化，必须初始化之后才能用
	var map1 = make(map[int]string)
	map1[1] = "A"
	map1[2] = "B" // 没有就直接添加
	fmt.Println(map1[2])
	var map2 = map[int]string{
		1: "A",
		2: "B",
	}
	fmt.Println(map2)
	map3 := map[int]string{
		1: "A",
		2: "B",
	}
	fmt.Println(map3)

	// 2. 循环遍历
	for key, value := range map1 {
		fmt.Println(key, value)
	}

	// 3. curd：创建（Create）、更新（Update）、读取（Retrieve）和删除（Delete）操作
	// c
	var userInfo = map[string]string{
		"sysdba": "sysdba",
		"UN":     "PWD",
	}
	// u
	userInfo["test"] = "test" // 不存在就添加
	fmt.Println(userInfo)
	userInfo["UN"] = "pwd" // 存在就修改
	fmt.Println(userInfo)
	// r
	fmt.Println(userInfo["admin"])
	value, isExist := userInfo["demo"] // 返回value值，以及是否存在，不存在value为_
	fmt.Println(value, isExist)
	value1, isExist1 := userInfo["test"] // 返回value值，以及是否存在
	fmt.Println(value1, isExist1)
	// d
	fmt.Println(userInfo)
	delete(userInfo, "sysdba")
	fmt.Println(userInfo)

	// 4. 元素为map的切片
	var test = make([]map[int]int, 3, 3)
	if test[0] == nil {
		test[0] = make(map[int]int)
		test[0][1] = 10
	}
	fmt.Println(test)

	// 5. 元素为切片的map
	var demo = make(map[int][]string)
	demo[1] = []string{"one", "ONE", "First"}
	fmt.Println(demo)

	// 6. map是引用类型

	// 7. 按照key升序输出, 可以单独将key存至slice中，排序slice，然后返回去输出map

	// 8. 练习
	var str = "a b c a d d j o m j a l y a j b z d x y i o p l m n r"
	s := strings.Split(str, " ")
	var m = make(map[string]int)
	for _, v := range s {
		m[v]++
	}
	fmt.Println(m)
*/
// }
